import React, { useState, useEffect } from 'react';
import type { SelectProps } from 'antd';
import { Select } from 'antd';
import _ from 'lodash';

const TjSelect: React.FC<ITjSelectProps> = (props) => {
  const { options, useDataObject, mapping, ...stdProps } = props;
  const [value, setValue] = useState<any>(null);
  const [tjOptions, setTjOptions] = useState<ITjSelectProps['options']>([]);

  const onChange = (value: any, option: any) => {
    if (_.isObject(useDataObject)) {
      const labelKey = _.get(useDataObject, 'label', 'label');
      const valueKey = _.get(useDataObject, 'value', 'value');
      if (props.mode === 'multiple' || props.mode === 'tags') {
        const arr = [];
        if (option.length > 0) {
          for (let i = 0; i < option.length; i++) {
            let item = option[i];
            const newItem: any = {};
            if (Object.keys(item).length === 0 && props.mode === 'tags') {
              item = {
                label: value[i],
                value: value[i],
              };
            }
            newItem[labelKey] = item.children || item.label;
            newItem[valueKey] = item.value;
            arr.push(newItem);
          }
        }
        props.onChange && props.onChange(arr, option);
      } else {
        const obj: any = {};
        obj[labelKey] = option ? option.children || option.label : undefined;
        obj[valueKey] = value;
        props.onChange && props.onChange(obj, option);
      }
    } else {
      props.onChange && props.onChange(value, option);
    }
  };

  useEffect(() => {
    if (props.value && useDataObject) {
      if (props.mode === 'multiple' || props.mode === 'tags') {
        const arr = props.value.map((v: any) => v[useDataObject.value]);
        setValue(arr);
      } else {
        const val = _.get(props.value, useDataObject.value, undefined);
        setValue(val);
      }
    } else {
      setValue(props.value);
    }
  }, [props.value]);

  useEffect(() => {
    if (props.options && _.isArray(props.options) && props.options.length > 0) {
      if (mapping) {
        const newOptions = props.options.map((v) => {
          const item: any = {
            label: '',
            value: '',
          };
          if (_.isString(mapping) && mapping === 'array') {
            item.label = v;
            item.value = v;
          }
          if (mapping && _.isObject(mapping)) {
            item.label = v[(mapping as any).label];
            item.value = v[(mapping as any).value];
          }
          return item;
        });
        setTjOptions(newOptions);
      } else {
        setTjOptions(props.options);
      }
    } else {
      setTjOptions([]);
    }
  }, [options]);

  return <Select {...stdProps} options={tjOptions} onChange={onChange} value={value} />;
};

interface ITjSelectProps extends SelectProps<any> {
  mapping?: 'array' | { label: string; value: string };
  useDataObject?: { label: string; value: string };
}

export default TjSelect;
